{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 神经网络解决多分类问题¶\n",
    "## 案例： 手写数字识别\n",
    "## 数据集：ex4data1.mat\n",
    "## 初始参数：ex4weights.mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy.io as sio\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.optimize import minimize"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = sio.loadmat('ex4data1.mat')\n",
    "raw_X = data['X']\n",
    "raw_y = data['y']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5000, 401)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = np.insert(raw_X,0,values=1,axis=1)\n",
    "X.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. 对y进行独热编码处理：one-hot编码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def one_hot_encoder(raw_y):\n",
    "    \n",
    "    result = []\n",
    "    \n",
    "    for i in raw_y: # 1-10\n",
    "        y_temp = np.zeros(10)\n",
    "        y_temp[i-1] = 1 \n",
    "        \n",
    "        result.append(y_temp)\n",
    "        \n",
    "    return np.array(result)\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = one_hot_encoder(raw_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5000, 10)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((25, 401), (10, 26))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta = sio.loadmat('ex4weights.mat')\n",
    "\n",
    "theta1, theta2 = theta['Theta1'],theta['Theta2']\n",
    "theta1.shape,theta2.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.序列化权重参数\n",
    "变成1列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def serialize(a,b):\n",
    "    \n",
    "    return np.append(a.flatten(),b.flatten())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "theta_serialize = serialize(theta1,theta2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(10285,)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta_serialize.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.解序列化权重参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def deserialize(theta_serialize):\n",
    "    theta1 = theta_serialize[:25*401].reshape(25,401) # 初始到25*401\n",
    "    theta2 = theta_serialize[25*401:].reshape(10,26) # 从25*401到后面所有\n",
    "    return theta1,theta2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "theta1,theta2 = deserialize(theta_serialize)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((25, 401), (10, 26))"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta1.shape,theta2.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.前向传播"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sigmoid(z):\n",
    "    return 1 / (1 + np.exp(-z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def feed_forward(theta_serialize,X):\n",
    "    theta1,theta2 = deserialize(theta_serialize)\n",
    "    a1 = X\n",
    "    z2 = a1 @ theta1.T\n",
    "    a2 = sigmoid(z2)\n",
    "    a2 = np.insert(a2,0,values=1,axis=1)\n",
    "    z3 = a2 @ theta2.T\n",
    "    h = sigmoid(z3)\n",
    "    return a1,z2,a2,z3,h"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.损失函数\n",
    "#### 5-1 不带正则化的损失函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cost(theta_serialize,X,y):\n",
    "    a1,z2,a2,z3,h = feed_forward(theta_serialize,X)\n",
    "    J = -np.sum(y*np.log(h)+(1-y)*np.log(1-h)) / len(X)\n",
    "    return J"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.2876291651613189"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cost(theta_serialize,X,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 5-2 带正则化的损失函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def reg_cost(theta_serialize,X,y,lamda):\n",
    "    sum1 = np.sum(np.power(theta1[:,1:],2))\n",
    "    sum2 = np.sum(np.power(theta2[:,1:],2))\n",
    "    reg = (sum1 + sum2) * lamda / (2*len(X))\n",
    "    return reg + cost(theta_serialize,X,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.38376985909092365"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lamda = 1\n",
    "reg_cost(theta_serialize,X,y,lamda)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.反向传播\n",
    "### 6-1 无正则化的梯度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 这是sigmod求导\n",
    "def sigmoid_gradient(z):\n",
    "    return sigmoid(z)*(1-sigmoid(z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gradient(theta_serialize,X,y):\n",
    "    theta1,theta2 = deserialize(theta_serialize)\n",
    "    a1,z2,a2,z3,h = feed_forward(theta_serialize,X)\n",
    "    d3 = h - y\n",
    "    # theta2[:,1:] 不要第1列 常数项（因为求不求导 不影响 最后损失 反而影响运算速度）\n",
    "    d2 = d3 @ theta2[:,1:] * sigmoid_gradient(z2)\n",
    "    D2 = (d3.T @ a2) / len(X)\n",
    "    D1 = (d2.T @ a1) / len(X)\n",
    "    return serialize(D1,D2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6-2 带正则化的梯度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def reg_gradient(theta_serialize,X,y,lamda):\n",
    "    D = gradient(theta_serialize,X,y)\n",
    "    D1,D2 = deserialize(D)\n",
    "    \n",
    "    theta1,theta2 = deserialize(theta_serialize)\n",
    "    D1[:,1:] = D1[:,1:]  + theta1[:,1:] * lamda / len(X)\n",
    "    D2[:,1:] = D2[:,1:]  + theta2[:,1:] * lamda / len(X)\n",
    "    \n",
    "    return serialize(D1,D2)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7.神经网络优化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.optimize import minimize\n",
    "\n",
    "def nn_training(X,y):\n",
    "    \n",
    "    init_theta = np.random.uniform(-0.5,0.5,10285)\n",
    "    res = minimize(fun =reg_cost,\n",
    "                   x0 = init_theta,\n",
    "                  args = (X,y,lamda),\n",
    "                  method='TNC',\n",
    "                  jac = reg_gradient,\n",
    "                options = {'maxiter':300})\n",
    "    \n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "lamda=10\n",
    "res = nn_training(X,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "raw_y = data['y'].reshape(5000,)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9408"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_,_,_,_,h = feed_forward(res.x,X)\n",
    "y_pred = np.argmax(h,axis=1) + 1\n",
    "acc = np.mean(y_pred == raw_y)\n",
    "\n",
    "acc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8.可视化隐藏层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_hidden_layer(theta):\n",
    "    theta1,_ = deserialize(theta)\n",
    "    hidden_layer = theta1[:,1:] # 25,400\n",
    "    \n",
    "    \n",
    "    fig,ax = plt.subplots(ncols=5,nrows=5,figsize=(8,8),sharex=True,sharey=True)\n",
    "    \n",
    "    for r in range(5):\n",
    "        for c in range(5):\n",
    "            \n",
    "            ax[r,c].imshow(hidden_layer[5 * r + c].reshape(20,20).T,cmap='gray_r')\n",
    "            \n",
    "    \n",
    "    plt.xticks([])\n",
    "    plt.yticks([])\n",
    "    \n",
    "    plt.show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 25 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_hidden_layer(res.x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
